/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "sle_lite_tool_test.h"
#include "kh_sle_ssap_server.h"
#include <time.h>
#include <cmsis_os2.h>
static uint8_t g_delayTestServerId = 0;
static uint16_t g_delayTestServiceHandle = 0;
static uint16_t g_delayTestPropertyHandle = 0;
static uint16_t g_DelayTestConnectId = 0;

void OnSleDelayTestExchangeMtuInfo(SleErrorCode errCode, uint8_t serverId, uint16_t connectId, const SsapMtuInfo *mtuInfo)
{
    if(connectId != g_DelayTestConnectId) return;
    printf("[SleDelayTestServer]OnSleDelayTestExchangeMtuInfo(%lu) serverId(%d) connectId(%d) mtuInfo(%ld)\r\n"
        , errCode, serverId, connectId, mtuInfo->mtuSize);
}

void OnSleDelayTestWriteRequestCallback(SleErrorCode errCode, uint8_t serverId,
         uint16_t connectId, const SsapsReqWriteCbPara *writeCbPara)
{
    if(connectId != g_DelayTestConnectId || serverId != g_delayTestServerId) return;
    //统计
    static uint64_t startTime = 0;
    static uint64_t endTime = 0;
    static uint16_t dataNum = 0;
    // start
    if(dataNum == 0) {
        startTime = uapi_tcxo_get_us();
    }
    // end
    if(++dataNum == Delay_Test_Time) {
        endTime = uapi_tcxo_get_us();
        dataNum = 0;
        uint64_t diffTime = endTime - startTime;
        printf("[SleDelayTestServer] connectId:%d, loss:(%d/%d), delay_avg=%lluus, payLoadLen=%ldbytes, throughout=%luKbps\r\n"
            , connectId, writeCbPara->value[0] - Delay_Test_Time, Delay_Test_Time, diffTime/Delay_Test_Time
            , writeCbPara->valueLen, writeCbPara->valueLen * Delay_Test_Time * 1000 / (diffTime * 1024));
    }
}

static SleErrorCode RegisterDelayTestServerCbs(void)
{
    static SleSsapsCallbacks ssapsCbk = {0};
    ssapsCbk.OnChangeMtuCb = OnSleDelayTestExchangeMtuInfo;
    ssapsCbk.OnRequestWriteCb = OnSleDelayTestWriteRequestCallback;
    RegisterSsapServerCallbacks(&ssapsCbk);
}

static SleErrorCode CreateDelayTestService(void)
{
    // add server
    SleUuid delayTestUuid;
    memcpy(delayTestUuid.uuid, "sleToolSsaps", strlen("sleToolSsaps") + 1);
    delayTestUuid.len = strlen("sleToolSsaps") + 1;
    SleErrorCode ret = AddSsapServer(&delayTestUuid, &g_delayTestServerId);
    if (ret != SLE_NO_ERROR) {
        printf("[SleDelayTestServer]AddSsapServer failed(%lu)\r\n", ret);
        return ret;
    }
    //add service
    memcpy(delayTestUuid.uuid, "DelayTestSrvi", strlen("DelayTestSrvi") + 1);
    delayTestUuid.len =  strlen("DelayTestSrvi") + 1;
    ret = AddService(g_delayTestServerId, &delayTestUuid, true, &g_delayTestServiceHandle);
    if (ret != SLE_NO_ERROR) {
        printf("[SleDelayTestServer]AddService failed(%lu)\r\n", ret);
        return ret;
    }
    //add property

    SsapsPropertyParam propertyParam = {
        .permissions = SSAP_PERMISSION_CAN_WRITE | SSAP_PERMISSION_CAN_READ,
        .opIndication = SSAP_OPERATEIND_BIT_WRITE | SSAP_OPERATEIND_BIT_WRITE_NO_RSP | SSAP_OPERATEIND_BIT_READ,
        .valueLen = strlen("DelayTestProp"),
        .value = "DelayTestProp",
    };
    memcpy(propertyParam.uuid.uuid, "DelayTestProp", strlen("DelayTestProp") + 1);
    propertyParam.uuid.len =  strlen("DelayTestProp") + 1;
    ret = AddProperty(g_delayTestServerId, g_delayTestServiceHandle, &propertyParam, &g_delayTestPropertyHandle);
    if ( ret != SLE_NO_ERROR) {
        printf("[SleDelayTestServer]AddProperty failed(%lu)\r\n", ret);
        return ret;
    }
    //start service
    ret = StartService(g_delayTestServerId, g_delayTestServiceHandle);
    if (ret != SLE_NO_ERROR) {
        printf("[SleDelayTestServer]StartService failed(%lu)\r\n", ret);
        return ret;
    }
    return SLE_NO_ERROR;
}

static SleErrorCode InitDelayTestServer(void)
{
    //注册ssap server回调
    SleErrorCode ret = RegisterDelayTestServerCbs();
    if(ret != SLE_NO_ERROR) {
        printf("[SleDelayTestServer]RegisterDelayTestServerCbs failed(%lu)\r\n", ret);
        return ret;
    }
    //创建delay test server service
   ret = CreateDelayTestService();
   if(ret != SLE_NO_ERROR) {
        printf("[SleDelayTestServer]CreateDelayTestService failed(%lu)\r\n", ret);
        return ret;
    }
    return SLE_NO_ERROR;
}

void DelayTestServer(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    g_DelayTestConnectId =  SleGetInputNumber("please input connectId:");
    if (CheckIsConnected(g_DelayTestConnectId) != SLE_NO_ERROR) {
        SLE_TEST_TOOL_LOG("[SleDelayTestClient]connectId(%d) is not connected", g_DelayTestConnectId);
        return;
    }
    ret = InitDelayTestServer();
    if(ret != SLE_NO_ERROR) {
        printf("[SleDelayTestServer]InitDelayTestServer failed(%lu)\r\n", ret);
        goto fail;
    }
    return;
fail:
    return;
}